﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Project.ServiceInterface.Base;
using Project.Biz.Base;
using System.ServiceModel;
using Project.Common;

namespace Project.Server.Base
{
	public class BaseService
	{
		public BaseService()
		{
			InjectBizObject.Inject(this);
		}
	}

	public class BaseService<T, BizT> : IBaseService<T> where BizT : IBiz<T>
	{
		public BizT BizAccess
		{
			get
			{
				return BizFactory.Get<BizT>();
			}
		}
		public BaseService()
		{
			InjectBizObject.Inject(this);
		}

		public IList<T> ListIn(string collection, Serialize.Linq.Nodes.ExpressionNode path)
		{
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.ListIn(collection, pathExpression);
		}

		public IList<T> List(Serialize.Linq.Nodes.ExpressionNode path, Project.Common.EnumOrder direction)
		{
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.List(pathExpression, direction);
		}

		public IList<T> List()
		{
			return BizAccess.List();
		}

		public IList<T> List(string path, string direction)
		{
			return BizAccess.List(path, direction);
		}

		public IList<T> List(params Common.LinqOrderSerialized<T>[] orderCollection)
		{
			return BizAccess.List(ConvertFromSerialized(orderCollection));
		}

		public IList<T> List(string path, Common.EnumOrder direction)
		{
			return BizAccess.List(path, direction);
		}

		public IList<T> ListBy(Serialize.Linq.Nodes.ExpressionNode criteria, Serialize.Linq.Nodes.ExpressionNode path, Project.Common.EnumOrder direction)
		{
			var criteriaExpression = criteria == null ? null : criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.ListBy(criteriaExpression, pathExpression, direction);
		}

		public IList<T> ListBy(Serialize.Linq.Nodes.ExpressionNode criteria, string path, Project.Common.EnumOrder direction)
		{
			var criteriaExpression = criteria == null ? null : criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.ListBy(criteriaExpression, path, direction);
		}

		public IList<T> ListBy(Serialize.Linq.Nodes.ExpressionNode criteria)
		{
			var criteriaExpression = criteria == null ? null : criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.ListBy(criteriaExpression);
		}

		public IList<T> ListBy(Serialize.Linq.Nodes.ExpressionNode criteria, string path, string direction)
		{
			var criteriaExpression = criteria == null ? null : criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.ListBy(criteriaExpression, path, direction);
		}

		public IList<T> ListBy(Serialize.Linq.Nodes.ExpressionNode criteria, params Common.LinqOrderSerialized<T>[] orderCollection)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.ListBy(criteriaExpression, ConvertFromSerialized(orderCollection));
		}

		public IList<T> ListTopX(Serialize.Linq.Nodes.ExpressionNode criteria, int count, Serialize.Linq.Nodes.ExpressionNode path, Project.Common.EnumOrder direction)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.ListTopX(criteriaExpression, count, pathExpression, direction);
		}

		public IList<T> PaginateListBy(int pageSize, int pageIndex, ref int count, Serialize.Linq.Nodes.ExpressionNode criteria, Serialize.Linq.Nodes.ExpressionNode path, Project.Common.EnumOrder direction)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.PaginateListBy(pageSize, pageIndex, ref count, criteriaExpression, pathExpression, direction);
		}

		public IList<T> PaginateListBy(int pageSize, int pageIndex, ref int count, Serialize.Linq.Nodes.ExpressionNode criteria, string path, Project.Common.EnumOrder direction)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.PaginateListBy(pageSize, pageIndex, ref count, criteriaExpression, path, direction);
		}

		public IList<T> PaginateListBy(int pageSize, int pageIndex, ref int count, Serialize.Linq.Nodes.ExpressionNode criteria)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.PaginateListBy(pageSize, pageIndex, ref count, criteriaExpression);
		}

		public int Count()
		{
			return BizAccess.Count();
		}

		public int CountBy(Serialize.Linq.Nodes.ExpressionNode criteria)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.CountBy(criteriaExpression);
		}

		public void Save(T entity)
		{
			BizAccess.Save(entity);
		}

		public void Update(T entity)
		{
			BizAccess.Update(entity);
		}

		public void Delete(T entity)
		{
			BizAccess.Delete(entity);
		}

		public void SaveOrUpdate(T entity)
		{
			BizAccess.SaveOrUpdate(entity);
		}

		public T Merge(T entity)
		{
			return BizAccess.Merge(entity);
		}

		public void Persist(T entity)
		{
			BizAccess.Persist(entity);
		}

		public T GetFirst(Serialize.Linq.Nodes.ExpressionNode criteria, Serialize.Linq.Nodes.ExpressionNode path, Project.Common.EnumOrder direction)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.GetFirst(criteriaExpression, pathExpression, direction);
		}

		public T GetFirst(Serialize.Linq.Nodes.ExpressionNode criteria)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.GetFirst(criteriaExpression);
		}

		public T GetFirst(Serialize.Linq.Nodes.ExpressionNode criteria, params Common.LinqOrderSerialized<T>[] orderCollection)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.GetFirst(criteriaExpression, ConvertFromSerialized(orderCollection));
		}

		public T GetFirst()
		{
			return BizAccess.GetFirst();
		}

		public T GetFirst(Serialize.Linq.Nodes.ExpressionNode path, Common.EnumOrder direction)
		{
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.GetFirst(pathExpression, direction);
		}

		public IList<T> ListTopX(Serialize.Linq.Nodes.ExpressionNode criteria, int count)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.ListTopX(criteriaExpression, count);
		}

		public IList<T> ListTopX(Serialize.Linq.Nodes.ExpressionNode criteria, int count, params Common.LinqOrderSerialized<T>[] orderCollection)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.ListTopX(criteriaExpression, count, ConvertFromSerialized(orderCollection));
		}

		public IList<T> PaginateList(int pageSize, int pageIndex, ref int count, Serialize.Linq.Nodes.ExpressionNode path, Common.EnumOrder direction)
		{
			var pathExpression = path == null ? null : path.ToExpression<Func<T, object>>();
			return BizAccess.PaginateList(pageSize, pageIndex, ref count, pathExpression, direction);
		}

		public IList<T> PaginateList(int pageSize, int pageIndex, ref int count, string path, Common.EnumOrder direction)
		{
			return BizAccess.PaginateList(pageSize, pageIndex, ref count, path, direction);
		}

		public IList<T> PaginateList(int pageSize, int pageIndex, ref int count, string path, string direction)
		{
			return BizAccess.PaginateList(pageSize, pageIndex, ref count, path, direction);
		}

		public IList<T> PaginateList(int pageSize, int pageIndex, ref int count)
		{
			return BizAccess.PaginateList(pageSize, pageIndex, ref count);
		}

		public IList<T> PaginateList(int pageSize, int pageIndex, ref int count, params Common.LinqOrderSerialized<T>[] orderCollection)
		{
			return BizAccess.PaginateList(pageSize, pageIndex, ref count, ConvertFromSerialized(orderCollection));
		}

		public IList<T> PaginateListBy(int pageSize, int pageIndex, ref int count, Serialize.Linq.Nodes.ExpressionNode criteria, string path, string direction)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.PaginateListBy(pageSize, pageIndex, ref count, criteriaExpression, path, direction);
		}

		public IList<T> PaginateListBy(int pageSize, int pageIndex, ref int count, Serialize.Linq.Nodes.ExpressionNode criteria, params Common.LinqOrderSerialized<T>[] orderCollection)
		{
			var criteriaExpression = criteria == null ? null : criteria.ToExpression<Func<T, bool>>();
			return BizAccess.PaginateListBy(pageSize, pageIndex, ref count, criteriaExpression, ConvertFromSerialized(orderCollection));
		}

		public T GetByID(object id)
		{
			return BizAccess.GetByID(id);
		}

		public void DeleteByID(object id)
		{
			BizAccess.DeleteByID(id);
		}


		private LinqOrder<T>[] ConvertFromSerialized(LinqOrderSerialized<T>[] orderCollection)
		{
			IList<LinqOrder<T>> targetCollection = new List<LinqOrder<T>>();
			foreach (var item in orderCollection)
			{
				var pathExpression = item.Path == null ? null : item.Path.ToExpression<Func<T, object>>();
				LinqOrder<T> targetItem = new LinqOrder<T>()
				{
					 Direction = item.Direction,
					 Path = pathExpression
				};
				targetCollection.Add(targetItem);
			}
			return targetCollection.ToArray();
		}

	}
}
